package com.uduemc.biso.node.web.api.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.uduemc.biso.core.utils.JsonResult;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.node.core.dto.FeignFindInfosByHostSiteAndSystemTypeIds;
import com.uduemc.biso.node.core.dto.FeignReplaceSCategoriesQuote;
import com.uduemc.biso.node.core.dto.FeignSystemDataInfos;
import com.uduemc.biso.node.core.entities.*;
import com.uduemc.biso.node.core.feign.SSystemFeign;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.web.api.component.RequestHolder;
import com.uduemc.biso.node.web.api.dto.RequestUpdateItemCategory;
import com.uduemc.biso.node.web.api.pojo.ResponseTableInfoSSystem;
import com.uduemc.biso.node.web.api.service.*;
import com.uduemc.biso.node.web.api.service.fegin.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SystemServiceImpl implements SystemService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    // 允许带系统表单的系统类型有哪些，目前只有 带分类产品系统 支持。
    public static final Long[] AllowFormSystemType = new Long[]{3L};

    @Resource
    private SSystemFeign sSystemFeign;

    @Resource
    private PageService pageServiceImpl;

    @Resource
    private RequestHolder requestHolder;

    @Resource
    private ObjectMapper objectMapper;

    @Resource
    private CategoryService categoryServiceImpl;

    @Resource
    private SystemTypeService systemTypeServiceImpl;

    @Resource
    private ContentService contentServiceImpl;

    @Resource
    private SArticleService sArticleServiceImpl;

    @Resource
    private SProductService sProductServiceImpl;

    @Resource
    private SDownloadService sDownloadServiceImpl;

    @Resource
    private InformationService informationServiceImpl;

    @Resource
    private SFaqService sFaqServiceImpl;

    @Resource
    private SPdtableService sPdtableServiceImpl;

    @Override
    public List<SSystem> getInfosByHostSiteId() throws JsonParseException, JsonMappingException, JsonProcessingException, IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        return getInfosByHostSiteId(hostId, siteId);
    }

    @Override
    public List<SSystem> getInfosByHostSiteId(Long hostId, Long siteId) throws IOException {
        RestResult restResult = sSystemFeign.findSSystemByHostSiteId(hostId, siteId);
        @SuppressWarnings("unchecked")
        List<SSystem> data = (List<SSystem>) RestResultUtil.data(restResult,
                objectMapper.getTypeFactory().constructParametricType(ArrayList.class, SSystem.class));
        return data;
    }

    @Override
    public List<SSystem> getInfosByHostSiteFormId(Long hostId, Long siteId, long formId) throws IOException {
        RestResult restResult = sSystemFeign.findSSystemByHostSiteFormId(hostId, siteId, formId);
        @SuppressWarnings("unchecked")
        List<SSystem> data = (List<SSystem>) RestResultUtil.data(restResult,
                objectMapper.getTypeFactory().constructParametricType(ArrayList.class, SSystem.class));
        return data;
    }

    @Override
    public List<SSystem> getInfosByHostSiteFormId(long formId) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        return getInfosByHostSiteFormId(hostId, siteId, formId);
    }

    @Override
    public SSystem getInfoById(Long id) throws IOException {
        if (id == null || id.longValue() < 1) {
            return null;
        }
        RestResult findOne = sSystemFeign.findOne(id);
        return RestResultUtil.data(findOne, SSystem.class);
    }

    @Override
    public SSystem getInfoById(Long id, Long hostId, Long siteId) throws IOException {
        RestResult restResult = sSystemFeign.findByIdAndHostSiteId(id, hostId, siteId);
        return RestResultUtil.data(restResult, SSystem.class);
    }

    @Override
    public SSystem getCurrentInfoById(Long id) throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        return getInfoById(id, hostId, siteId);
    }

    @Override
    public ResponseTableInfoSSystem getTableInfoSSysTem(SSystem sSystem) throws IOException {
        ResponseTableInfoSSystem responseTableInfoSSystem = new ResponseTableInfoSSystem();
        responseTableInfoSSystem.setId(sSystem.getId());
        responseTableInfoSSystem.setName(sSystem.getName());
        responseTableInfoSSystem.setSystemType(systemTypeServiceImpl.getInfoById(sSystem.getSystemTypeId()));
        responseTableInfoSSystem.setConfig(sSystem.getConfig());
        // 获取挂载页面
        List<SPage> infosBySystemId = pageServiceImpl.getInfosBySystemId(sSystem.getId());
        if (CollectionUtils.isEmpty(infosBySystemId)) {
            responseTableInfoSSystem.setPages("暂时未挂载页面");
        } else {
            StringBuilder pages = new StringBuilder();
            int time = 0;
            for (SPage sPage : infosBySystemId) {
                if (time != 0) {
                    pages.append("、");
                }
                pages.append(sPage.getName());
                time++;
            }
            responseTableInfoSSystem.setPages(pages.toString());
        }

        String statistics = "默认未定义";
        if (responseTableInfoSSystem.getSystemType().getId().longValue() == 1L) {
            int totalCategory = categoryServiceImpl.totalCurrentBySystemId(sSystem.getId());
            int totalArticle = contentServiceImpl.totalArticleCurrentBySystemId(sSystem.getId());
            statistics = "分类数：" + totalCategory + "， 文章数：" + totalArticle;
        } else if (responseTableInfoSSystem.getSystemType().getId().longValue() == 2L) {
            int totalCurrentBySystemId2 = contentServiceImpl.totalArticleCurrentBySystemId(sSystem.getId());
            statistics = "内容数：" + totalCurrentBySystemId2;
        } else if (responseTableInfoSSystem.getSystemType().getId().longValue() == 3L) {
            int totalCategory = categoryServiceImpl.totalCurrentBySystemId(sSystem.getId());
            int totalProduct = contentServiceImpl.totalProductCurrentBySystemId(sSystem.getId());
            statistics = "分类数：" + totalCategory + "， 产品数：" + totalProduct;
        } else if (responseTableInfoSSystem.getSystemType().getId().longValue() == 5L) {
            int totalCategory = categoryServiceImpl.totalCurrentBySystemId(sSystem.getId());
            int totalDownload = contentServiceImpl.totalDownloadCurrentBySystemId(sSystem.getId());
            statistics = "分类数：" + totalCategory + "， 文件数：" + totalDownload;
        } else if (responseTableInfoSSystem.getSystemType().getId().longValue() == 6L) {
            int totalCategory = categoryServiceImpl.totalCurrentBySystemId(sSystem.getId());
            int totalDownload = contentServiceImpl.totalFaqCurrentBySystemId(sSystem.getId());
            statistics = "分类数：" + totalCategory + "， Faq数：" + totalDownload;
        } else if (responseTableInfoSSystem.getSystemType().getId().longValue() == 7L) {
            int totalInformationTitle = informationServiceImpl.totalSInformationTitleByHostSiteSystemId(sSystem.getId());
            int totalInformation = contentServiceImpl.totalInformationCurrentBySystemId(sSystem.getId());
            statistics = "属性数：" + totalInformationTitle + "， 信息数：" + totalInformation;
        } else if (responseTableInfoSSystem.getSystemType().getId().longValue() == 8L) {
            int totalCategory = categoryServiceImpl.totalCurrentBySystemId(sSystem.getId());
            int totalDownload = contentServiceImpl.totalPdtableCurrentBySystemId(sSystem.getId());
            statistics = "分类数：" + totalCategory + "， 产品表格数：" + totalDownload;
        }

        // 获取统计
        responseTableInfoSSystem.setStatistics(statistics);
        return responseTableInfoSSystem;
    }

    @Override
    public List<ResponseTableInfoSSystem> getTableInfoSSysTem(List<SSystem> infos)
            throws IOException {
        if (CollectionUtils.isEmpty(infos)) {
            return null;
        }
        List<ResponseTableInfoSSystem> result = new ArrayList<>();
        ResponseTableInfoSSystem responseTableInfoSSystem = null;
        for (SSystem sSystem : infos) {
            responseTableInfoSSystem = getTableInfoSSysTem(sSystem);
            result.add(responseTableInfoSSystem);
        }
        return result;
    }

    @Override
    public List<ResponseTableInfoSSystem> getCurrentTableInfoSSysTem() throws IOException {
        List<SSystem> infos = getInfosByHostSiteId();
        return getTableInfoSSysTem(infos);
    }

    @Override
    public SSystem insertSSystem(SSystem sSystem) throws IOException {
        RestResult restResult = sSystemFeign.insert(sSystem);
        SSystem data = RestResultUtil.data(restResult, SSystem.class);
        return data;
    }

    @Override
    public SSystem updateSSystem(SSystem sSystem) throws IOException {
        RestResult restResult = sSystemFeign.updateById(sSystem);
        SSystem data = RestResultUtil.data(restResult, SSystem.class);
        return data;
    }

    @Override
    public List<SSystem> updateSSystemFormIdZero(SForm sForm) throws IOException {
        if (sForm == null) {
            return null;
        }
        Long hostId = sForm.getHostId();
        Long siteId = sForm.getSiteId();
        Long id = sForm.getId();
        List<SSystem> listSSystem = getInfosByHostSiteFormId(hostId, siteId, id);
        if (CollUtil.isNotEmpty(listSSystem)) {
            List<SSystem> result = new ArrayList<>(listSSystem.size());
            for (SSystem sSystem : listSSystem) {
                sSystem.setFormId(0L);
                result.add(updateSSystem(sSystem));
            }
            return result;
        }
        return null;
    }

    @Override
    public boolean delete(long id) throws IOException {
        RestResult restResult = sSystemFeign.deleteSystemByIdHostSiteId(id, requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId());
        SSystem data = RestResultUtil.data(restResult, SSystem.class);
        if (data == null || data.getId().longValue() != id) {
            return false;
        }
        return true;
    }

    @Override
    public List<SSystem> getInfosByType(long hostId, long siteId, List<Long> systemTypeIds)
            throws IOException {
        FeignFindInfosByHostSiteAndSystemTypeIds feignParam = new FeignFindInfosByHostSiteAndSystemTypeIds();
        feignParam.setHostId(hostId).setSiteId(siteId).setSystemTypeIds(systemTypeIds);
        RestResult restResult = sSystemFeign.findInfosByHostSiteAndSystemTypeIds(feignParam);
        logger.info(restResult.toString());
        @SuppressWarnings("unchecked")
        List<SSystem> data = (List<SSystem>) RestResultUtil.data(restResult,
                objectMapper.getTypeFactory().constructParametricType(ArrayList.class, SSystem.class));
        return data;
    }

    @Override
    public List<SSystem> getCurrentInfosByType(List<Long> systemTypeIds) throws IOException {
        return getInfosByType(requestHolder.getHost().getId(), requestHolder.getCurrentSite().getId(), systemTypeIds);
    }

    @Override
    public JsonResult updateItemCategory(RequestUpdateItemCategory requestUpdateItemCategory)
            throws IOException {
        long systemId = requestUpdateItemCategory.getSystemId();
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        SSystem sSystem = getInfoById(systemId, hostId, siteId);
        if (sSystem == null) {
            return JsonResult.illegal();
        }

        Long systemTypeId = sSystem.getSystemTypeId();
        if (systemTypeId == null) {
            return JsonResult.assistance();
        }

        List<Long> itemIds = requestUpdateItemCategory.getItemIds();
        if (CollUtil.isEmpty(itemIds)) {
            return JsonResult.illegal();
        }

        List<Long> categoryIds = requestUpdateItemCategory.getCategoryIds();
        if (CollUtil.isNotEmpty(categoryIds)) {
            boolean existCurrentBySystemCagetoryIds = categoryServiceImpl.existCurrentBySystemCagetoryIds(systemId, categoryIds);
            if (!existCurrentBySystemCagetoryIds) {
                return JsonResult.illegal();
            }
        }

        FeignSystemDataInfos feignSystemDataInfos = new FeignSystemDataInfos();
        feignSystemDataInfos.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setIds(itemIds);
        if (systemTypeId == 1) {
            // 文章系统
            List<SArticle> listSArticle = sArticleServiceImpl.findInfosByHostSiteSystemAndIds(feignSystemDataInfos);
            if (listSArticle.size() != itemIds.size()) {
                return JsonResult.illegal();
            }
        } else if (systemTypeId == 3L) {
            // 产品系统
            List<SProduct> listSProduct = sProductServiceImpl.findInfosByHostSiteSystemAndIds(feignSystemDataInfos);
            if (listSProduct.size() != itemIds.size()) {
                return JsonResult.illegal();
            }
        } else if (systemTypeId == 5L) {
            // 下载系统
            List<SDownload> listSDownload = sDownloadServiceImpl.findInfosByHostSiteSystemAndIds(feignSystemDataInfos);
            if (listSDownload.size() != itemIds.size()) {
                return JsonResult.illegal();
            }
        } else if (systemTypeId == 6L) {
            // FAQ系统
            List<SFaq> listSFaq = sFaqServiceImpl.findInfosByHostSiteSystemAndIds(feignSystemDataInfos);
            if (listSFaq.size() != itemIds.size()) {
                return JsonResult.illegal();
            }
        } else if (systemTypeId == 8L) {
            // 产品表格系统
            List<SPdtable> listSPdtable = sPdtableServiceImpl.findInfosByHostSiteSystemAndIds(feignSystemDataInfos);
            if (listSPdtable.size() != itemIds.size()) {
                return JsonResult.illegal();
            }
        } else {
            return JsonResult.messageError("未能识别的系统类型！");
        }

        // 修改产品分类
        FeignReplaceSCategoriesQuote feignReplaceSCategoriesQuote = new FeignReplaceSCategoriesQuote();
        feignReplaceSCategoriesQuote.setHostId(hostId).setSiteId(siteId).setSystemId(systemId).setCategoryIds(categoryIds).setItemIds(itemIds);
        if (!categoryServiceImpl.replaceSCategoriesQuote(feignReplaceSCategoriesQuote)) {
            return JsonResult.assistance();
        }
        return JsonResult.ok(1);
    }

    @Override
    public List<SSystem> allowMountFormSystemList(long hostId, long siteId) throws IOException {
        List<SSystem> listSSystem = getInfosByHostSiteId(hostId, siteId);
        List<SSystem> result = new ArrayList<>();
        if (CollUtil.isEmpty(listSSystem)) {
            return result;
        }
        return listSSystem.stream().filter(item -> allowMountForm(item)).collect(Collectors.toList());
    }

    @Override
    public List<SSystem> allowMountFormSystemList() throws IOException {
        Long hostId = requestHolder.getHost().getId();
        Long siteId = requestHolder.getCurrentSite().getId();
        return allowMountFormSystemList(hostId, siteId);
    }

    @Override
    public boolean allowMountForm(SSystem system) {
        if (system == null) {
            return false;
        }
        Long systemTypeId = system.getSystemTypeId();
        Long formId = system.getFormId();
        // 目前支持带分类的产品系统
        return systemTypeId != null && ArrayUtil.contains(AllowFormSystemType, systemTypeId) && formId != null && formId.longValue() == 0;
    }

    @Override
    public SSystem mountForm(SSystem system, SForm sForm) throws IOException {
        if (system == null || sForm == null) {
            return null;
        }
        system.setFormId(sForm.getId());
        return updateSSystem(system);
    }

}
